package com.baizhi.aspect;
import com.baizhi.annotation.LogAnnotation;
import com.baizhi.entity.CmfzAdmin;
import com.baizhi.entity.CmfzLog;
import com.baizhi.mapper.CmfzLogMapper;
import com.baizhi.util.IPKit;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
@Aspect //定义当前类为切面类
@Configuration //定义当前类为配置类
public class LogAspect {
    @Autowired
    private JmsTemplate jmsTemplate;
    @Autowired
    private CmfzLogMapper cmfzLogMapper;
    /*
    *1. 创建一个后置增强
    *
    * 2.设置切入点  切注解
    * @annotation(com.baizhi.annotation.LogAnnotation)
    *  设置切入点为所有方法只要使用@annotation注解都会被切入
    * */
    @After("@annotation(com.baizhi.annotation.LogAnnotation)")
    public void logAfter(JoinPoint joinPoint) throws JsonProcessingException {
        /*
        * 3.采集日志数据封装到对象中
        *       1.日志的主键 自增
        *       2.管理员的id session中获取
        *       3.日期   new  Date（）
        *       4.ip  工具类
        *       5.操作内容   从自定义注解中获取
        *       6.操作类型   从自定义注解中获取
        * */
        CmfzLog cmfzLog = new CmfzLog();
        /*
        * 从session中获取登录后的管理员对象
        *
        * ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        *  HttpServletRequest request = requestAttributes.getRequest();
        *  上面两行代码 可以在项目任何位置拿到request
        *
        * */
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();

        CmfzAdmin admin = (CmfzAdmin) request.getSession().getAttribute("admin");

        if (admin != null){
            cmfzLog.setAdminId(admin.getId());
        }else {
            /*
            * 如果admin对象为空  代表没有登录 用0表示
            * */
            cmfzLog.setAdminId(0);
        }
        /*
        * 获取日期
        * */
        cmfzLog.setLogDate(new Date());
        /*
        * 获取ip方法
        * 1.request.getRemoteAddr()获取远程地址
        * 2.一般情况会采用工具类 ip的获取都是基础功能 公司项目一般都有
        * */
        String ip = IPKit.getIpAddrByRequest(request);
        cmfzLog.setLogIp(ip);

        /*
        * 获取操作内容 和操作类型
        * 解决方案：通过自定义注解
        * 因为每个方法上的注解内容都是不一样的  所有获取到内容也不一样
        *
        * 步骤：
        *   1.自定义注解
        *   2. 在增强中获取被切入的 方法上的注解  JoinPoint
        *   3. 获取注解的值
        * */
        //获取到方法  获取注解属性 方法签名对象
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //通过方法签名对象获取到方法对象
        Method method = signature.getMethod();
        /*通过方法对象获取方法上的注解*/
        LogAnnotation annotation = method.getAnnotation(LogAnnotation.class);
        /*获取注解中的值*/
        String content = annotation.content();
        String type = annotation.type();
        /*给对象赋值*/
        cmfzLog.setLogContent(content);
        cmfzLog.setLogType(type);
        System.out.println(cmfzLog);
        /*
        * 将java对象转换为json 用的是jackson
        * cmfzLogJson json对象
        *
        * */
        ObjectMapper objectMapper = new ObjectMapper();
        String cmfzLogJson = objectMapper.writeValueAsString(cmfzLog);
        jmsTemplate.send("mq-boot", new MessageCreator() {
            @Override
            public Message createMessage(Session session) throws JMSException {
                return session.createTextMessage(cmfzLogJson);
            }
        });
       /* *//*将对象添加到数据库中*//*
        cmfzLogMapper.insert(cmfzLog);*/
    }
}
